1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| #include<bits/stdc++.h> using namespace std; typedef long long s64;
const int ONE = 200005; const int INF = 2147483640;
int get() { int res = 1, Q = 1; char c; while( (c = getchar()) < 48 || c > 57) if(c == '-') Q = -1; if(Q) res = c - 48; while( (c = getchar()) >= 48 && c <= 57) res = res * 10 + c - 48; return res * Q; }
int n; int a[ONE];
struct point { int id, val; friend bool operator <(point a, point b) { if(a.val != b.val) return a.val < b.val; return a.id < b.id; } }; point res;
namespace Seg { struct power {point odd, eve;} Node[ONE * 4];
void Build(int i, int l, int r) { Node[i].odd.val = Node[i].eve.val = INF; if(l == r) { if(l & 1) Node[i].odd = (point){l, a[l]}; else Node[i].eve = (point){l, a[l]}; return; } int mid = l + r >> 1; Build(i << 1, l, mid), Build(i << 1 | 1, mid + 1, r); Node[i].odd = min(Node[i << 1].odd, Node[i << 1 | 1].odd); Node[i].eve = min(Node[i << 1].eve, Node[i << 1 | 1].eve); }
void Query(int i, int l, int r, int L, int R, int opt) { if(L <= l && r <= R) { if(opt == 1) res = min(res, Node[i].odd); else res = min (res, Node[i].eve); return; } int mid = l + r >> 1; if(L <= mid) Query(i << 1, l, mid, L, R, opt); if(mid + 1 <= R) Query(i << 1 | 1, mid + 1, r, L, R, opt); } }
struct power { int l, r, val; bool operator <(power a) const { if(a.val != val) return a.val < val; return a.l < l; } }; priority_queue <power> q;
point Get(int l, int r, int opt) { res = (point){n + 1, INF}; Seg::Query(1, 1, n, l, r, opt); return res; }
void Add(int l, int r) { if(l > r) return; q.push((power){l, r, Get(l, r, l % 2).val}); }
int main() { n = get(); for(int i = 1; i <= n; i++) a[i] = get();
Seg::Build(1, 1, n); Add(1, n);
for(int i = 1; i <= n / 2; i++) { power u = q.top(); q.pop(); point A = Get(u.l, u.r - 1, u.l % 2); point B = Get(A.id + 1, u.r, u.r % 2); printf("%d %d ", A.val, B.val);
Add(u.l, A.id - 1), Add(A.id + 1, B.id - 1), Add(B.id + 1, u.r); } }
|